package com.yimi.yinhepda.views.fenbo_ziti

import android.content.Intent
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.view.View
import com.pda.uce.commom.util.MyDialog
import com.yimi.yinhepda.R
import com.yimi.yinhepda.adapter.RecycleAdapter.FenBoZiTiAdapter
import com.pda.ym.callbacks.UICallBack
import com.yimi.yinhepda.db.dao.UnloadScanTableDao
import com.pda.ym.db.table.UnloadScanTable
import com.pda.ym.entity.response.NoDataResponse
import com.pda.ym.base.BaseTitleActivity
import com.yimi.yinhepda.entity.request.QueryCheckZiTiDestRequest
import com.yimi.yinhepda.entity.request.ScanLoadUploadRequest
import com.yimi.yinhepda.entity.response.*
import com.pda.ym.net.NetRequest
import com.pda.ym.utils.*
import com.yimi.yinhepda.utils.*
import com.yimi.yinhepda.views.load_module.BackoutActivity
import com.yimi.yinhepda.views.load_module.LoadUnloadGroupActivity
import kotlinx.android.synthetic.main.activity_fenbo_ziti.*
import java.io.Serializable
import java.math.BigDecimal
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set

/**
 * @author: lj
 * Date: 2020/3/9 10:59
 * Description:分拨自提界面
 */
class FenBoZiTiActivity : BaseTitleActivity(true) {

    companion object {
        //扫描列表集合
        var loadInfos = mutableListOf<LoadInfo>()
    }

    private var tempLoadInfos = mutableListOf<LoadInfo>()

    //自提部门code
    private val ziTiDeptCode: String by lazy { intent.getStringExtra("ziTiDeptCode") }
    private val ziTiDeptName: String by lazy { intent.getStringExtra("ziTiDeptName") }
    //参与人
    private val joinWrokNums: String by lazy { intent.getStringExtra("joinWrokNum") }
    private val joinUserNames: String by lazy { intent.getStringExtra("joinUserName") }
    //列表适配器
    private var adapter: FenBoZiTiAdapter? = null
    //数据库扫描表操作类
    private val unloadScanDao by lazy { UnloadScanTableDao() }
    private val userCode by lazy { sharedPreferUtil.getValue(Common.USER_CODE) }
    //自提失败集合
    private var errorList = mutableListOf<ZiTiScanUploadResponse.ApplyErrorInfo>()

    override fun getPageName(): String {
        return "分拨自提扫描"
    }

    override fun setContentViewId(): Int {
        return R.layout.activity_fenbo_ziti
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        btn_back.setOnClickListener(this)
        btn_ok.setOnClickListener(this)
        btn_del.setOnClickListener(this)

        //查询数据字典设置自提上传条数
        queryDictZiTiScanUploadNum()
    }

    override fun showBack(): Boolean {
        return false
    }

    override fun setBack() {
    }

    override fun setTitle(): String {
        return pageName
    }

    override fun onResume() {
        super.onResume()
        //加载本地已扫描数据
        loadLocalScanData()
    }

    /**
     * 加载本地已扫描数据
     */
    private fun loadLocalScanData() {
        //主单map
        val waybillMap = mutableMapOf<String, LoadInfo>()
        //子单map
        val childWaybillMap = mutableMapOf<String, QueryLoadDetailChildBillcode>()
        //查询本地已扫描的自提数据
        val findZiTiData = unloadScanDao.findZiTiData(ziTiDeptCode, userCode)
        findZiTiData.forEach {
            waybillMap[it.waybillNo] = createWaybillInfo(it)
            childWaybillMap[it.childWaybillNo] = createChildWaybillInfo(it.childWaybillNo)
        }
        loadInfos.clear()
        //子单添加到主单中，组装界面展示的扫描数据
        for ((key, value) in waybillMap) {
            value.childList = mutableListOf()
            for ((childKey, childValue) in childWaybillMap) {
                if (childKey.startsWith(key)) {
                    value.childList.add(childValue)
                }
            }
            //添加到集合中用于展示
            loadInfos.add(value)
        }
        //加载UI列表适配器
        loadUiAdapter(loadInfos)
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.btn_del -> {
                val intent = Intent(this, BackoutActivity::class.java)
                intent.putExtra("delType", 1)
                intent.putExtra("ziTiDeptCode", ziTiDeptCode)
                startActivity(intent)
            }
            R.id.btn_back -> finish()
            R.id.btn_ok -> submitData()
        }
    }

    override fun handleBarCode(result: String?) {
        if (result == null) {
            SoundVibratorManager.playSound(2)
            showToast("运单号扫描失败")
        } else {
            if (!FastClick.isFastClickScanner()) {
                doScan(result)
            }
        }
    }

    /**
     * 处理扫描的运单
     */
    private fun doScan(result: String?) {
        if (!StringUtils.isWaybillNo(result) && !StringUtils.isPackgeNo(result) && !UcWaybillValidate.validate(result)) {
            SoundVibratorManager.playSound(2)
            showToast("单号或包号不规范!")
            return
        }

        loadInfos.forEach {
            if (result!!.startsWith(it.waybillNo)) {
                it.childList?.forEach { child ->
                    if (child.childWaybillNo == result) {
                        SoundVibratorManager.playSound(2)
                        showToast("运单号已扫描！")
                        return
                    }
                }
                if (result.substring(12).toInt() > it.srcPiecesNum) {
                    SoundVibratorManager.playSound(2)
                    showToast("该运单号大于开单件数！")
                    return
                }
                //创建扫描表对象保存至本地
                createInsertScanTableByLoadInfo(result, it)

                //创建子单
                val childWaybill = createChildWaybillInfo(result)
                //添加到子单集合中
                it.childList.add(childWaybill)
                loadInfos.remove(it)
                loadInfos.add(0, it)
                //加载UI列表适配器
                loadUiAdapter(loadInfos)
                return
            }
        }

        showPgDlg("运单查询中...")
        disableScan()
        //本地没有该运单，调经营接，查询是否可以改单
        val request = QueryCheckZiTiDestRequest()
        request.waybillNo = result?.substring(0, 12)?.toLong()!!
        request.destZoneCode = ziTiDeptCode
        request.destZoneName = ziTiDeptName
        request.changeDataSourceType = 1
        NetRequest().setMethod(NetRequest.Method.POST_STRING)
                .setResponsClazz(ZiTiCheckResponse::class.java)
                .setUrl(Constants.URL_ZI_TI_CHECK_DEST_ZONE)
                .setRequestObject(request)
                .execute(object : UICallBack() {
                    override fun onSuccess(obj: Any?) {
                        enableScan()
                        dismissPgDlg()
                        val response = obj as ZiTiCheckResponse
                        if (response.data?.success == 1) {
                            //运单查询改单失败
                            val data = response.data
                            MyDialog.showAlertDialog(this@FenBoZiTiActivity, "运单号：${data.waybillNo}不能进行自提\n" +
                                    "原因：${data.errorMsg}")
                        } else {
                            //可以改单,查询运单详情，获取界面所需元素
                            queryWayBillInfo(result, response.data?.success)
                        }
                    }

                    override fun onError(msg: String?) {
                        enableScan()
                        dismissPgDlg()
                        showToast(msg)
                    }
                })
    }

    /**
     * 创建扫描表对象保存至本地
     */
    private fun createInsertScanTableByLoadInfo(result: String?, loadInfo: LoadInfo) {
        val waybillInfo = WaybillExtend()
        waybillInfo.waybillNo = loadInfo.waybillNo.toLong()
        waybillInfo.quantity = loadInfo.srcPiecesNum
        waybillInfo.waybillType = loadInfo.kyWaybillType.toInt()
        waybillInfo.realWeight = loadInfo.weight
        waybillInfo.volume = loadInfo.volume
        waybillInfo.paidPaymentAmount = loadInfo.paidPaymentAmount
        waybillInfo.goodsChargeFee = loadInfo.goodsChargeFee
        waybillInfo.singBackType = loadInfo.singBackType
        createInsertScanTable(result, waybillInfo, loadInfo.isZiTi)
    }

    /**
     * 创建扫描表对象保存至本地
     */
    private fun createInsertScanTable(result: String?, waybillInfo: WaybillExtend, successType: Int?): UnloadScanTable {
        val scanTable = UnloadScanTable()
        scanTable.waybillNo = waybillInfo.waybillNo.toString()
        scanTable.childWaybillNo = result
        scanTable.operTypeCode = Common.FEN_BO_ZI_TI_SCAN_TYPE
        scanTable.inputType = 1
        //约定此字段为分拨自提部门code
        scanTable.areaCode = ziTiDeptCode
        scanTable.operEmpCode = sharedPreferUtil.getValue(Common.USER_CODE)
        scanTable.operEmpName = sharedPreferUtil.getValue(Common.USER_NAME)
        scanTable.operTime = Constants.GetSysTime()
        scanTable.scanTime = Constants.GetScanTime()
        scanTable.deptCode = sharedPreferUtil.deptCode
        scanTable.deviceCode = SysInfo.getInstance().imei
        scanTable.operPersonCodes = joinWrokNums
        scanTable.operPersonNames = joinUserNames
        scanTable.deptType = sharedPreferUtil.getIntValue(Common.DEPT_TYPE)
        scanTable.waybillType = 1
        scanTable.srcPiecesNum = waybillInfo.quantity
        scanTable.kyWaybillType = waybillInfo.waybillType
        scanTable.singBackType = waybillInfo.singBackType
        scanTable.weight = waybillInfo.realWeight
        scanTable.volume = waybillInfo.volume
        scanTable.paidPaymentAmount = waybillInfo.paidPaymentAmount
        scanTable.goodsChargeFee = waybillInfo.goodsChargeFee
        scanTable.singBack = waybillInfo.singBack
        scanTable.isZiTi = successType
        unloadScanDao.insert(scanTable)
        return scanTable
    }

    /**
     * 创建主单对象
     */
    private fun createWaybillInfo(scanTable: UnloadScanTable): LoadInfo {
        val loadInfo = LoadInfo()
        loadInfo.waybillNo = scanTable.waybillNo.toString()
        loadInfo.srcPiecesNum = scanTable.srcPiecesNum
        loadInfo.kyWaybillType = scanTable.waybillType.toString()
        loadInfo.weight = scanTable.weight
        loadInfo.volume = scanTable.volume
        loadInfo.paidPaymentAmount = scanTable.paidPaymentAmount
        loadInfo.goodsChargeFee = scanTable.goodsChargeFee
        loadInfo.singBack = scanTable.singBack
        loadInfo.singBackType = scanTable.singBackType
        loadInfo.isZiTi = scanTable.isZiTi
        return loadInfo
    }

    /**
     * 创建子单对象
     */
    private fun createChildWaybillInfo(childWayBillNo: String?): QueryLoadDetailChildBillcode {
        val childWaybill = QueryLoadDetailChildBillcode()
        childWaybill.childWaybillNo = childWayBillNo
        childWaybill.flag = 1
        return childWaybill
    }

    /**
     * 加载UI列表适配器
     */
    private fun loadUiAdapter(list: MutableList<LoadInfo>?) {
        //排序
        val templist = sortList(list)
        if (adapter == null) {
            adapter = FenBoZiTiAdapter(this@FenBoZiTiActivity, templist)
            rv_ziTi_list.layoutManager = LinearLayoutManager(this@FenBoZiTiActivity, LinearLayoutManager.VERTICAL, false)
            rv_ziTi_list.adapter = adapter
        } else {
            adapter!!.notifyDataSetChanged()
        }
        //统计运单数据
        collectData()
        SoundVibratorManager.playSound(1)
    }

    /**
     * 统计运单数据
     */
    private fun collectData() {
        //扫描票数
        val piaoNum = loadInfos.size
        //扫描件数
        var jianNum = 0
        //扫描重量
        var weight = 0.0
        //扫描体重
        var volume = 0.0
        //到付金额
        var daofuMount = 0.0
        //代收货款
        var daishouMount = 0.0
        loadInfos.forEach {
            jianNum += it.childList.size
            weight += BigDecimalUtils.mul(BigDecimalUtils.div(it.weight.toDouble(), it.srcPiecesNum.toDouble(), 4), it.childList.size.toDouble())
            volume += BigDecimalUtils.mul(BigDecimalUtils.div(it.volume.toDouble(), it.srcPiecesNum.toDouble(), 4), it.childList.size.toDouble())
            daofuMount += it.paidPaymentAmount.toDouble()
            daishouMount += it.goodsChargeFee.toDouble()
        }
        tv_ziTi_piao.text = piaoNum.toString()
        tv_ziTi_jian.text = jianNum.toString()
        tv_ziTi_weight.text = BigDecimalUtils.round(weight, 2).toString()
        tv_ziTi_volume.text = BigDecimalUtils.round(volume, 2).toString()
        tv_daoFu_mount.text = BigDecimalUtils.round(daofuMount, 2).toString()
        tv_daiShou_mount.text = BigDecimalUtils.round(daishouMount, 2).toString()
        //应收合计
        tv_total_mount.text = BigDecimalUtils.round(daofuMount + daishouMount, 2).toString()
    }

    /**
     * 查询运单详情
     */
    private fun queryWayBillInfo(result: String?, successType: Int?) {
        showPgDlg("正在查询运单...")
        val params = HashMap<String, String>(1)
        params["waybillNoArray"] = result?.substring(0, 12).toString()

        NetRequest().setMethod(NetRequest.Method.GET)
                .setResponsClazz(QueryWybillExtendVoByWaybillNoArrayResponse::class.java)
                .setUrl(Constants.URL_GETWAYBILL)
                .setParams(params)
                .execute(object : UICallBack() {
                    override fun onSuccess(obj: Any?) {
                        dismissPgDlg()
                        val response = obj as QueryWybillExtendVoByWaybillNoArrayResponse
                        val waybillList = response.data?.waybillExtendList
                        if (waybillList.isNullOrEmpty()) {
                            showToast("无该运单信息！")
                        } else {
                            val waybillInfo = waybillList[0]
                            if (result?.substring(12)?.toInt()!! > waybillInfo.quantity) {
                                SoundVibratorManager.playSound(2)
                                showToast("该运单号大于开单件数！")
                                return
                            }
                            //创建扫描表对象保存至本地
                            val scanTable = createInsertScanTable(result, waybillInfo, successType)
                            //创建主单对象
                            val loadInfo = createWaybillInfo(scanTable)
                            //创建子单对象
                            val childWaybill = createChildWaybillInfo(result)
                            //创建子单集合
                            loadInfo.childList = mutableListOf()
                            loadInfo.childList.add(childWaybill)
                            //添加到集合中用于展示
                            loadInfos.add(0, loadInfo)
                            //加载UI列表适配器
                            loadUiAdapter(loadInfos)
                            //查询的运单有到付金额、代收货款时提示
                            if (waybillInfo.paidPaymentAmount.compareTo(BigDecimal.ZERO) == 1
                                    || waybillInfo.goodsChargeFee.compareTo(BigDecimal.ZERO) == 1) {
                                MyDialog.showAlertDialog(this@FenBoZiTiActivity,
                                        "请注意\n运单号：${waybillInfo.waybillNo}\n到付金额：${waybillInfo.paidPaymentAmount}元\n" +
                                                "代收货款：${waybillInfo.goodsChargeFee}元\n" +
                                                "合计：${waybillInfo.paidPaymentAmount + waybillInfo.goodsChargeFee}元")
                            }
                        }
                    }

                    override fun onError(msg: String?) {
                        dismissPgDlg()
                        showToast(msg)
                    }
                })
    }

    /**
     * 确定提交数据
     */
    private fun submitData() {
        if (loadInfos.isNullOrEmpty()) {
            showToast("无提交数据！")
            SoundVibratorManager.playSound(2)
            return
        }
        MyDialog.showAlertDialog(this, "确定提交？", "确定", "取消",
                { dialog, _ ->
                    dialog.dismiss()
                    //先提交分拨自提数据，再上传扫描数据
                    tempLoadInfos.clear()
                    tempLoadInfos.addAll(loadInfos)
                    submitZiTiData()
                }, { dialog, _ -> dialog.dismiss() })
    }

    /**
     * 提交分拨自提数据
     */
    private fun submitZiTiData() {
        if (!tempLoadInfos.isNullOrEmpty()) {
            showPgDlg("提交数据中...")
            val list = mutableListOf<QueryCheckZiTiDestRequest>()
            val tempInfos = if (tempLoadInfos.size >= Common.ZITI_SCAN_UPLOAD_NUM) {
                tempLoadInfos.subList(0, Common.ZITI_SCAN_UPLOAD_NUM)
            } else {
                tempLoadInfos.subList(0, tempLoadInfos.size)
            }
            val findZiTiData = unloadScanDao.findZiTiData(ziTiDeptCode, userCode)
            tempInfos.forEach {
                //无需改单，不需要提交改单
                if (it.isZiTi == 2) {
                    findZiTiData.forEach { ziTiData ->
                        if (it.waybillNo == ziTiData.waybillNo) {
                            //修改自提状态
                            ziTiData.isZiTi = 2
                            unloadScanDao.update(ziTiData)
                        }
                    }
                } else {
                    val item = QueryCheckZiTiDestRequest()
                    item.waybillNo = it.waybillNo.toLong()
                    item.destZoneCode = ziTiDeptCode
                    item.destZoneName = ziTiDeptName
                    item.changeDataSourceType = 1
//            item.destZoneCode = "371A"
//            item.destZoneName = "郑州驻地营业部"
                    list.add(item)
                }
            }

            if (!list.isNullOrEmpty()) {
                NetRequest().setMethod(NetRequest.Method.POST_STRING)
                        .setResponsClazz(ZiTiScanUploadResponse::class.java)
                        .setUrl(Constants.URL_UPDATE_WAYBILL_DEST_ZONE)
                        .setRequestObject(list)
                        .execute(object : UICallBack() {
                            override fun onSuccess(obj: Any?) {
                                dismissPgDlg()
                                val response = obj as ZiTiScanUploadResponse
                                //获取改单失败的运单集合
                                errorList = response.data
                                findZiTiData.forEach { ziTiData ->
                                    //修改自提状态
                                    ziTiData.isZiTi = 1
                                    unloadScanDao.update(ziTiData)
                                    //处理改单失败的运单
                                    if (!errorList.isNullOrEmpty()) {
                                        errorList.forEach { error ->
                                            //删除扫描表中自提失败的运单
                                            if (ziTiData.waybillNo == error.waybillNo.toString()) {
                                                unloadScanDao.delete(ziTiData)
                                            }
                                        }
                                    }
                                }

                                //删除集合中已经上传的运单
                                tempLoadInfos.iterator().run {
                                    while (this.hasNext()) {
                                        this.next().run {
                                            list.forEach {
                                                if (it.waybillNo.toString() == this.waybillNo) {
                                                    remove()
                                                }
                                            }
                                        }
                                    }
                                }
                                //继续提交数据
                                submitZiTiData()
                            }

                            override fun onError(msg: String?) {
                                dismissPgDlg()
                                showToast(msg)
                            }
                        })
            } else {
                //上传扫描表数据
                uploadScanData()
            }
        } else {
            //上传扫描表数据
            uploadScanData()
        }
    }

    /**
     * 上传扫描表数据
     */
    private fun uploadScanData() {
        showPgDlg("上传数据中...")
        //扫描上传的虚拟任务号=纳秒时间戳
        val scanTaskNo = System.nanoTime().toString()
        val list = unloadScanDao.findZiTiByUpload(ziTiDeptCode, userCode, 100)
        if (list.isNotEmpty()) {
            list.forEach {
                //约定此字段为分拨自提扫描任务号
                it.stowageNo = scanTaskNo
            }
            val mScanLoadUploadRequest = ScanLoadUploadRequest()
            mScanLoadUploadRequest.records = list
            NetRequest().setMethod(NetRequest.Method.POST_STRING)
                    .setResponsClazz(NoDataResponse::class.java)
                    .setUrl(Constants.UPLOAD_ZITI_DATA_URL)
                    .setRequestObject(mScanLoadUploadRequest)
                    .execute(object : UICallBack() {
                        override fun onSuccess(obj: Any?) {
                            list.forEach {
                                //设置为已上传状态
                                it.isUpload = 1
                                unloadScanDao.update(it)
                            }
                            //继续遍历未上传的扫描数据
                            uploadScanData()
                        }

                        override fun onError(msg: String?) {
                            dismissPgDlg()
                            showToast(msg)
                        }
                    })
        } else {
            //有提交数据失败返回，则显示失败列表
            goToFailActiviity()
        }
    }

    /**
     * 有提交数据失败返回，则显示失败列表
     */
    private fun goToFailActiviity() {
        dismissPgDlg()
        finish()
        ActivityStack.getInstance().activities.forEach breaking@{
            if (it is LoadUnloadGroupActivity) {
                it.finish()
                return@breaking
            }
        }
        if (!errorList.isNullOrEmpty()) {
            val intent = Intent(this@FenBoZiTiActivity, FenBoZiTiFailActivity::class.java)
            intent.putExtra("errorList", errorList as Serializable)
            startActivity(intent)
        } else {
            showToast("提交成功！")
        }
    }

    /**
     * 数据排序
     * 一级排序 红>黄>白>绿,getType
     */
    private fun sortList(list: MutableList<LoadInfo>?): MutableList<LoadInfo>? {
        list?.forEach {
            it.firstSort = it.type
        }
        val sortNameArr = arrayOf("firstSort")
        // true升序,false降序
        val isAscArr = booleanArrayOf(true)
        ListUtils.sort(list, sortNameArr, isAscArr)
        return list
    }

    /**
     * 查询数据字典自提上传条数：ziti_scan_upload_num
     */
    private fun queryDictZiTiScanUploadNum() {
        val params = mutableMapOf<String, String>()
        params["dictCode"] = "ziti_scan_upload_num"
        //查询类型，1-只查询未作废的，为null则查询所有(包含作废和未作废的)
        params["type"] = "1"
        NetRequest().setMethod(NetRequest.Method.GET)
                .setResponsClazz(QueryBaseDictResponse::class.java)
                .setUrl(Constants.URL_QUERY_DICT)
                .setParams(params)
                .execute(object : UICallBack() {
                    override fun onError(msg: String) {
                        ToastUtil.showToast(msg)
                    }

                    override fun onSuccess(obj: Any) {
                        val response = obj as QueryBaseDictResponse
                        if (response.data != null) {
                            val dictlist = response.data
                            if (!dictlist.isNullOrEmpty()) {
                                val entity = dictlist[0]
                                try {
                                    Common.ZITI_SCAN_UPLOAD_NUM = entity.dictValue.toInt()
                                } catch (e: NumberFormatException) {
                                    e.printStackTrace()
                                }
                            }
                        }
                    }
                })
    }

    override fun onDestroy() {
        super.onDestroy()
        if (!loadInfos.isNullOrEmpty()) {
            loadInfos.clear()
        }
    }
}



